home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / larn.lha / create.c < prev    next >
C/C++ Source or Header  |  1995-11-19  |  16KB  |  486 lines

  1. /* create.c */
  2. #include "header.h"
  3. #include "larndefs.h"
  4. #include "monsters.h"
  5. #include "objects.h"
  6. #include "player.h"
  7.  
  8. /*
  9.     makeplayer()
  10.  
  11.     subroutine to create the player and the players attributes
  12.     this is called at the beginning of a game and at no other time
  13.  */
  14. makeplayer()
  15.     {
  16.     register int i;
  17.     scbr();  clear();
  18.     c[HPMAX]=c[HP]=10;      /*  start player off with 15 hit points */
  19.     c[LEVEL]=1;             /*  player starts at level one          */
  20.     c[SPELLMAX]=c[SPELLS]=1;    /*  total # spells starts off as 3  */
  21.     c[REGENCOUNTER]=16;     c[ECOUNTER]=96; /*start regeneration correctly*/
  22.     c[SHIELD] = c[WEAR] = c[WIELD] = -1;
  23.     for (i=0; i<26; i++)  iven[i]=0;
  24.     spelknow[0]=spelknow[1]=1; /*he knows protection, magic missile*/
  25.     if (c[HARDGAME]<=0)
  26.         {
  27.         iven[0]=OLEATHER; iven[1]=ODAGGER; iven[2] = 0;
  28.         ivenarg[1]=ivenarg[0]=c[WEAR]=0;  c[WIELD]=1;
  29.         }
  30.     playerx=rnd(MAXX-2);    playery=rnd(MAXY-2);
  31.     regen_bottom = TRUE ;
  32.     for (i=0; i<6; i++)  c[i]=12; /* make the attributes, ie str, int, etc. */
  33.     recalc();
  34.     }
  35.  
  36. /*
  37.     newcavelevel(level)
  38.     int level;
  39.  
  40.     function to enter a new level.  This routine must be called anytime the
  41.     player changes levels.  If that level is unknown it will be created.
  42.     A new set of monsters will be created for a new level, and existing
  43.     levels will get a few more monsters.
  44.     Note that it is here we remove genocided monsters from the present level.
  45.  */
  46. newcavelevel(x)
  47.     register int x;
  48.     {
  49.     register int i,j;
  50.     if (beenhere[level]) savelevel();   /* put the level back into storage  */
  51.     level = x;              /* get the new level and put in working storage */
  52.     if (beenhere[x])
  53.         {
  54.         getlevel();
  55.         sethp(0);
  56.         positionplayer();
  57.         checkgen();
  58.         return;
  59.         }
  60.  
  61.     /* fill in new level
  62.     */
  63.     for (i=0; i<MAXY; i++)
  64.         for (j=0; j<MAXX; j++)
  65.             know[j][i]=mitem[j][i]=0;
  66.     makemaze(x);
  67.     makeobject(x);
  68.     beenhere[x]=1;
  69.     sethp(1);
  70.     positionplayer();
  71.     checkgen();   /* wipe out any genocided monsters */
  72.  
  73. #if WIZID
  74.     if (wizard || x==0)
  75. #else
  76.     if (x==0)
  77. #endif
  78.         for (j=0; j<MAXY; j++)
  79.             for (i=0; i<MAXX; i++)
  80.                 know[i][j] = KNOWALL;
  81.     }
  82.  
  83. /*
  84.     makemaze(level)
  85.     int level;
  86.  
  87.     subroutine to make the caverns for a given level.  only walls are made.
  88.  */
  89. static int mx,mxl,mxh,my,myl,myh,tmp2;
  90. static makemaze(k)
  91.     int k;
  92.     {
  93.     register int i,j,tmp;
  94.     int z;
  95.     if (k > 1 && (rnd(17)<=4 || k==MAXLEVEL-1 || k==MAXLEVEL+MAXVLEVEL-1))
  96.         {
  97.         if (cannedlevel(k));    return;     /* read maze from data file */
  98.         }
  99.     if (k==0)  tmp=0;  else tmp=OWALL;
  100.     for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)  item[j][i]=tmp;
  101.     if (k==0) return;       eat(1,1);
  102.     if (k==1) item[33][MAXY-1] = OENTRANCE;
  103.  
  104. /*  now for open spaces -- not on level 10  */
  105.     if (k != MAXLEVEL-1)
  106.         {
  107.         tmp2 = rnd(3)+3;
  108.         for (tmp=0; tmp<tmp2; tmp++)
  109.             {
  110.             my = rnd(11)+2;   myl = my - rnd(2);  myh = my + rnd(2);
  111.             if (k < MAXLEVEL)
  112.                 {
  113.                 mx = rnd(44)+5;  mxl = mx - rnd(4);  mxh = mx + rnd(12)+3;
  114.                 z=0;
  115.                 }
  116.             else
  117.                 {
  118.                 mx = rnd(60)+3;  mxl = mx - rnd(2);  mxh = mx + rnd(2);
  119.                 z = makemonst(k);
  120.                 }
  121.             for (i=mxl; i<mxh; i++)     for (j=myl; j<myh; j++)
  122.                 {  item[i][j]=0;
  123.                    if ((mitem[i][j]=z)) hitp[i][j]=monster[z].hitpoints;
  124.                 }
  125.             }
  126.         }
  127.     if (k!=MAXLEVEL-1) { my=rnd(MAXY-2);  for (i=1; i<MAXX-1; i++)  item[i][my] = 0; }
  128.     if (k>1)  treasureroom(k);
  129.     }
  130.  
  131. /*
  132.     function to eat away a filled in maze
  133.  */
  134. eat(xx,yy)
  135.     register int xx,yy;
  136.     {
  137.     register int dir,try;
  138.     dir = rnd(4);   try=2;
  139.     while (try)
  140.         {
  141.         switch(dir)
  142.             {
  143.             case 1: if (xx <= 2) break;     /*  west    */
  144.                     if ((item[xx-1][yy]!=OWALL) || (item[xx-2][yy]!=OWALL)) break;
  145.                     item[xx-1][yy] = item[xx-2][yy] = 0;
  146.                     eat(xx-2,yy);   break;
  147.  
  148.             case 2: if (xx >= MAXX-3) break;    /*  east    */
  149.                     if ((item[xx+1][yy]!=OWALL) || (item[xx+2][yy]!=OWALL)) break;
  150.                     item[xx+1][yy] = item[xx+2][yy] = 0;
  151.                     eat(xx+2,yy);   break;
  152.  
  153.             case 3: if (yy <= 2) break;     /*  south   */
  154.                     if ((item[xx][yy-1]!=OWALL) || (item[xx][yy-2]!=OWALL)) break;
  155.                     item[xx][yy-1] = item[xx][yy-2] = 0;
  156.                     eat(xx,yy-2);   break;
  157.  
  158.             case 4: if (yy >= MAXY-3 ) break;   /*  north   */
  159.                     if ((item[xx][yy+1]!=OWALL) || (item[xx][yy+2]!=OWALL)) break;
  160.                     item[xx][yy+1] = item[xx][yy+2] = 0;
  161.                     eat(xx,yy+2);   break;
  162.             };
  163.         if (++dir > 4)  { dir=1;  --try; }
  164.         }
  165.     }
  166.  
  167. /*
  168.  *  function to read in a maze from a data file
  169.  *
  170.  *  Format of maze data file:  1st character = # of mazes in file (ascii digit)
  171.  *              For each maze: 18 lines (1st 17 used) 67 characters per line
  172.  *
  173.  *  Special characters in maze data file:
  174.  *
  175.  *      #   wall            D   door            .   random monster
  176.  *      ~   eye of larn     !   cure dianthroritis
  177.  *      -   random object
  178.  */
  179. static cannedlevel(k)
  180.     int k;
  181.     {
  182.     char *row,*lgetl();
  183.     register int i,j;
  184.     int it,arg,mit,marg;
  185.     if (lopen(larnlevels)<0)
  186.         {
  187.         write(1,"Can't open the maze data file\n",30);   died(-282); return(0);
  188.         }
  189.     i=lgetc();  if (i<='0') { died(-282); return(0); }
  190.     for (i=18*rund(i-'0'); i>0; i--)    lgetl();   /* advance to desired maze */
  191.     for (i=0; i<MAXY; i++)
  192.         {
  193.         row = lgetl();
  194.         for (j=0; j<MAXX; j++)
  195.             {
  196.             it = mit = arg = marg = 0;
  197.             switch(*row++)
  198.                 {
  199.                 case '#': it = OWALL;                               break;
  200.                 case 'D': it = OCLOSEDDOOR;     arg = rnd(30);      break;
  201.                 case '~': if (k!=MAXLEVEL-1) break;
  202.                           it = OLARNEYE;
  203.                           mit = rund(8)+DEMONLORD;
  204.                           marg = monster[mit].hitpoints;            break;
  205.                 case '!': if (k!=MAXLEVEL+MAXVLEVEL-1)  break;
  206.                           it = OPOTION;         arg = 21;
  207.                           mit = DEMONLORD+7;
  208.                           marg = monster[mit].hitpoints;            break;
  209.                 case '.': if (k<MAXLEVEL)  break;
  210.                           mit = makemonst(k+1);
  211.                           marg = monster[mit].hitpoints;            break;
  212.                 case '-': it = newobject(k+1,&arg);                 break;
  213.                 };
  214.             item[j][i] = it;        iarg[j][i] = arg;
  215.             mitem[j][i] = mit;      hitp[j][i] = marg;
  216.  
  217. #if WIZID
  218.             know[j][i] = (wizard) ? KNOWALL : 0;
  219. #else
  220.             know[j][i] = 0;
  221. #endif
  222.             }
  223.         }
  224.     lrclose();
  225.     return(1);
  226.     }
  227.  
  228. /*
  229.     function to make a treasure room on a level
  230.     level 10's treasure room has the eye in it and demon lords
  231.     level V3 has potion of cure dianthroritis and demon prince
  232.  */
  233. static treasureroom(lv)
  234.     register int lv;
  235.     {
  236.     register int tx,ty,xsize,ysize;
  237.  
  238.     for (tx=1+rnd(10);  tx<MAXX-10;  tx+=10)
  239.       if ( (lv==MAXLEVEL-1) || (lv==MAXLEVEL+MAXVLEVEL-1) || rnd(13)==2)
  240.         {
  241.         xsize = rnd(6)+3;       ysize = rnd(3)+3;  
  242.         ty = rnd(MAXY-9)+1;  /* upper left corner of room */
  243.         if (lv==MAXLEVEL-1 || lv==MAXLEVEL+MAXVLEVEL-1)
  244.             troom(lv,xsize,ysize,tx=tx+rnd(MAXX-24),ty,rnd(3)+6);
  245.             else troom(lv,xsize,ysize,tx,ty,rnd(9));
  246.         }
  247.     }
  248.  
  249. /*
  250.  *  subroutine to create a treasure room of any size at a given location 
  251.  *  room is filled with objects and monsters 
  252.  *  the coordinate given is that of the upper left corner of the room
  253.  */
  254. static troom(lv,xsize,ysize,tx,ty,glyph)
  255.     int lv,xsize,ysize,tx,ty,glyph;
  256.     {
  257.     register int i,j;
  258.     int tp1,tp2;
  259.     for (j=ty-1; j<=ty+ysize; j++)
  260.         for (i=tx-1; i<=tx+xsize; i++)          /* clear out space for room */
  261.             item[i][j]=0;
  262.     for (j=ty; j<ty+ysize; j++)
  263.         for (i=tx; i<tx+xsize; i++)             /* now put in the walls */
  264.             {
  265.             item[i][j]=OWALL; mitem[i][j]=0; 
  266.             }
  267.     for (j=ty+1; j<ty+ysize-1; j++)
  268.         for (i=tx+1; i<tx+xsize-1; i++)         /* now clear out interior */
  269.             item[i][j]=0;
  270.  
  271.     switch(rnd(2))      /* locate the door on the treasure room */
  272.         {
  273.         case 1: item[i=tx+rund(xsize)][j=ty+(ysize-1)*rund(2)]=OCLOSEDDOOR;
  274.                 iarg[i][j] = glyph;     /* on horizontal walls */
  275.                 break;
  276.         case 2: item[i=tx+(xsize-1)*rund(2)][j=ty+rund(ysize)]=OCLOSEDDOOR;
  277.                 iarg[i][j] = glyph;     /* on vertical walls */
  278.                 break;
  279.         };
  280.  
  281.     tp1=playerx;  tp2=playery;  playery=ty+(ysize>>1);
  282.     if (c[HARDGAME]<2)
  283.         for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
  284.             for (i=0, j=rnd(6); i<=j; i++)
  285.                 { something(lv+2); createmonster(makemonst(lv+1)); }
  286.     else
  287.         for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
  288.             for (i=0, j=rnd(4); i<=j; i++)
  289.                 { something(lv+2); createmonster(makemonst(lv+3)); }
  290.  
  291.     playerx=tp1;  playery=tp2;
  292.     }
  293.  
  294. /*
  295.     ***********
  296.     MAKE_OBJECT
  297.     ***********
  298.     subroutine to create the objects in the maze for the given level
  299.  */
  300. static makeobject(j)
  301.     register int j;
  302.     {
  303.     register int i;
  304.     if (j==0)
  305.         {
  306.         fillroom(OENTRANCE,0);      /*  entrance to dungeon         */
  307.         fillroom(ODNDSTORE,0);      /*  the DND STORE               */
  308.         fillroom(OSCHOOL,0);        /*  college of Larn             */
  309.         fillroom(OBANK,0);          /*  1st national bank of larn   */
  310.         fillroom(OVOLDOWN,0);       /*  volcano shaft to temple     */
  311.         fillroom(OHOME,0);          /*  the players home & family   */
  312.         fillroom(OTRADEPOST,0);     /*  the trading post            */
  313.         fillroom(OLRS,0);           /*  the larn revenue service    */
  314.         return;
  315.         }
  316.  
  317.     if (j==MAXLEVEL) fillroom(OVOLUP,0); /* volcano shaft up from the temple */
  318.  
  319. /*  make the fixed objects in the maze STAIRS   */
  320.     if ((j>0) && (j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
  321.         fillroom(OSTAIRSDOWN,0);
  322.     if ((j > 1) && (j != MAXLEVEL))
  323.         fillroom(OSTAIRSUP,0);
  324.  
  325. /*  make the random objects in the maze     */
  326.  
  327.     fillmroom(rund(3),OBOOK,j);             
  328.     fillmroom(rund(3),OALTAR,0);
  329.     fillmroom(rund(3),OSTATUE,0);           
  330.     fillmroom(rund(3),OPIT,0);
  331.     fillmroom(rund(3),OFOUNTAIN,0);         
  332.     fillmroom( rnd(3)-2,OIVTELETRAP,0);
  333.     fillmroom(rund(2),OTHRONE,0);           
  334.     fillmroom(rund(2),OMIRROR,0);
  335.     fillmroom(rund(2),OTRAPARROWIV,0);      
  336.     fillmroom( rnd(3)-2,OIVDARTRAP,0);
  337.     fillmroom(rund(3),OCOOKIE,0);
  338.     if (j==1) 
  339.         fillmroom(1,OCHEST,j);
  340.     else 
  341.         fillmroom(rund(2),OCHEST,j);
  342.     if ((j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
  343.         fillmroom(rund(2),OIVTRAPDOOR,0);
  344.     if (j<=10)
  345.         {
  346.         fillmroom((rund(2)),ODIAMOND,rnd(10*j+1)+10);
  347.         fillmroom(rund(2),ORUBY,rnd(6*j+1)+6);
  348.         fillmroom(rund(2),OEMERALD,rnd(4*j+1)+4);
  349.         fillmroom(rund(2),OSAPPHIRE,rnd(3*j+1)+2);
  350.         }
  351.     for (i=0; i<rnd(4)+3; i++)
  352.         fillroom(OPOTION,newpotion());  /*  make a POTION   */
  353.     for (i=0; i<rnd(5)+3; i++)
  354.         fillroom(OSCROLL,newscroll());  /*  make a SCROLL   */
  355.     for (i=0; i<rnd(12)+11; i++)
  356.         fillroom(OGOLDPILE,12*rnd(j+1)+(j<<3)+10); /* make GOLD */
  357.     if (j==5)   
  358.         fillroom(OBANK2,0);         /* branch office of the bank */
  359.     froom(2,ORING,0);               /* a ring mail          */
  360.     froom(1,OSTUDLEATHER,0);        /* a studded leather    */
  361.     froom(3,OSPLINT,0);             /* a splint mail        */
  362.     froom(5,OSHIELD,rund(3));       /* a shield             */
  363.     froom(2,OBATTLEAXE,rund(3));    /* a battle axe         */
  364.     froom(5,OLONGSWORD,rund(3));    /* a long sword         */
  365.     froom(5,OFLAIL,rund(3));        /* a flail              */
  366.     froom(4,OREGENRING,rund(3));    /* ring of regeneration */
  367.     froom(1,OPROTRING,rund(3));     /* ring of protection   */
  368.     froom(2,OSTRRING,1+rnd(3));     /* ring of strength     */
  369.     froom(7,OSPEAR,rnd(5));         /* a spear              */
  370.     froom(3,OORBOFDRAGON,0);        /* orb of dragon slaying*/
  371.     froom(4,OSPIRITSCARAB,0);       /* scarab of negate spirit*/
  372.     froom(4,OCUBEofUNDEAD,0);       /* cube of undead control   */
  373.     froom(2,ORINGOFEXTRA,0);        /* ring of extra regen      */
  374.     froom(3,ONOTHEFT,0);            /* device of antitheft      */
  375.     froom(2,OSWORDofSLASHING,0);    /* sword of slashing */
  376.     if (c[BESSMANN]==0)
  377.         {
  378.         froom(4,OHAMMER,0);/*Bessman's flailing hammer*/
  379.         c[BESSMANN]=1;
  380.         }
  381.     if (c[HARDGAME]<3 || (rnd(4)==3))
  382.         {
  383.         if (j>3)
  384.             {
  385.             froom(3,OSWORD,3);        /* sunsword + 3         */
  386.             froom(5,O2SWORD,rnd(4));  /* a two handed sword */
  387.             froom(3,OBELT,4);         /* belt of striking     */
  388.             froom(3,OENERGYRING,3);   /* energy ring          */
  389.             froom(4,OPLATE,5);        /* platemail + 5        */
  390.             froom(3,OCLEVERRING,1+rnd(2));  /* ring of cleverness */
  391.             }
  392.         }
  393.     }
  394.  
  395. /*
  396.     subroutine to fill in a number of objects of the same kind
  397.  */
  398.  
  399. static fillmroom(n,what,arg)
  400.     int n,arg;
  401.     char what;
  402.     {
  403.     register int i;
  404.     for (i=0; i<n; i++)     fillroom(what,arg);
  405.     }
  406. static froom(n,itm,arg)
  407.     int n,arg;
  408.     char itm;
  409.     {   if (rnd(151) < n) fillroom(itm,arg);    }
  410.  
  411. /*
  412.     subroutine to put an object into an empty room
  413.  *  uses a random walk
  414.  */
  415. static fillroom(what,arg)
  416.     int arg;
  417.     char what;
  418.     {
  419.     register int x,y;
  420.  
  421. #ifdef EXTRA
  422.     c[FILLROOM]++;
  423. #endif
  424.  
  425.     x=rnd(MAXX-2);  y=rnd(MAXY-2);
  426.     while (item[x][y])
  427.         {
  428.  
  429. #ifdef EXTRA
  430.         c[RANDOMWALK]++;    /* count up these random walks */
  431. #endif
  432.  
  433.         x += rnd(3)-2;      y += rnd(3)-2;
  434.         if (x > MAXX-2)  x=1;       if (x < 1)  x=MAXX-2;
  435.         if (y > MAXY-2)  y=1;       if (y < 1)  y=MAXY-2;
  436.         }
  437.     item[x][y]=what;        iarg[x][y]=arg;
  438.     }
  439.  
  440. /*
  441.     subroutine to put monsters into an empty room without walls or other
  442.     monsters
  443.  */
  444. fillmonst(what)
  445.     char what;
  446.     {
  447.     register int x,y,trys;
  448.     for (trys=5; trys>0; --trys) /* max # of creation attempts */
  449.       {
  450.       x=rnd(MAXX-2);  y=rnd(MAXY-2);
  451.       if ((item[x][y]==0) && (mitem[x][y]==0) && ((playerx!=x) || (playery!=y)))
  452.         {
  453.         mitem[x][y] = what;  know[x][y] &= ~KNOWHERE;
  454.         hitp[x][y] = monster[what].hitpoints;  return(0);
  455.         }
  456.       }
  457.     return(-1); /* creation failure */
  458.     }
  459.  
  460. /*
  461.     creates an entire set of monsters for a level
  462.     must be done when entering a new level
  463.     if sethp(1) then wipe out old monsters else leave them there
  464.  */
  465. static sethp(flg)
  466.     int flg;
  467.     {
  468.     register int i,j;
  469.     if (flg) for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) stealth[j][i]=0;
  470.     if (level==0) { c[TELEFLAG]=0; return; } /* if teleported and found level 1 then know level we are on */
  471.     if (flg)   j = rnd(12) + 2 + (level>>1);   else   j = (level>>1) + 1;
  472.     for (i=0; i<j; i++)  fillmonst(makemonst(level));
  473.     }
  474.  
  475. /*
  476.  *  Function to destroy all genocided monsters on the present level
  477.  */
  478. static checkgen()
  479.     {
  480.     register int x,y;
  481.     for (y=0; y<MAXY; y++)
  482.         for (x=0; x<MAXX; x++)
  483.             if (monster[mitem[x][y]].genocided)
  484.                 mitem[x][y]=0; /* no more monster */
  485.     }
  486.